/**
*		@file Uses.h
*		@brief Uses class
*
*		@author Kong Ling Ming
*
*		@date 1/25/2012
*/

#ifndef USES_H
#define USES_H

#include "TNode.h"
#include "VarTable.h"
#include "StmtTable.h"
#include "ProcTable.h"
#include <vector>
#include <sstream>
using namespace std;

/**
*		Structure to Uses relation for assignment
*/
struct UsesEntry{
	StmtNum		stmt_num;
	VarIdx		var_idx;
};

class Uses{
public:

	/**
	*		This method will set Uses(stmt_num_assign, var_idx)
	*		@param stmt_num_assign An assignment's StmtNum
	*/
	static void	SetUsesA(StmtNum stmt_num_assign, VarIdx var_idx);

	/**
	*		This method will transform a vector structure to a matrix structure
	*/
	static void		RebuildUses();

	static void		TransposeUses();

	static void		CompleteUses();
	/**
	*		This method will set var_set for stmt_num
	*/
	static void		SetUsesS(StmtNum stmt_num, VarSet var_set);

	/**
	*		This method will set var_set for proc_idx
	*/
	static void		SetUsesP(ProcIdx proc_idx, VarSet var_set);

	/**
	*		This method will return VarSet that are used by stmt_num
	*/
	static VarSet&	GetUsesS(StmtNum stmt_num);

	/**
	*		This method will return VarSet that are used by proc_idx
	*/
	static VarSet&	GetUsesP(ProcIdx proc_idx);

	/**
	*		This method will return StmtSet that uses var_idx
	*/
	static StmtSet&	GetUsesByS(VarIdx var_idx);

	/**
	*		This method will return ProSet that uses var_idx
	*/
	static ProcSet&	GetUsesByP(VarIdx var_idx);

	/**
	*		This method will check if Uses(stmt_num, var_idx)
	*/
	static bool		IsUsesS(StmtNum stmt_num, VarIdx var_idx);

	/**
	*		This method will check if Uses(proc_idx, var_idx)
	*/
	static bool		IsUsesP(ProcIdx proc_idx, VarIdx var_idx);

	/**
	*		This method will return a string representation of Uses relation
	*/
	static string	ToString();

private:
	static vector<UsesEntry*>	vp_uses_entries_;
	static vector<VarSet>		uses_stmt_table_;
	static vector<StmtSet>		uses_stmt_table_t_;

	static vector<VarSet>		uses_proc_table_;
	static vector<ProcSet>		uses_proc_table_t_;

	static StmtSet				uses_has_s0_;	//uses(s,_)
	static ProcSet				uses_has_p0_;	//uses(p,_)
	static VarSet				uses_has_0v_;	//uses(_,v)
	static bool					uses_has_00_;	//uses(_,_)
};

#endif